﻿package com.player;

import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.fastjson.JSONObject;
import com.mgr.DriverOrderMgr;
import com.mgr.UserOrderMgr;
import com.qy.DaoMgr;
import com.qy.bean.DriverInfo;
import com.qy.bean.Option;
import com.qy.bean.UserInfo;
import com.qy.util.LogUtil;
import com.qy.util.StaticData;
import com.qy.util.TimeUtil;


/**
 * 世界管理类(管理所有游戏玩家)
 * @author lym
 *
 */
public class WorldMgr {

	private static Map<Integer, DriverUser> driverUserMap;
	private static Map<Integer, CommonUser> commonUserMap;
	public static int SITE_ID; // 区服ID
	public static int CHANNEL_ID; // 渠道ID
//	private static long MAX_SITES = 10000L; // 最大区服（一万）
//	private static long MAX_PLAYERS = 10000000L; // 单服最大玩家数（一千万）

	/**
	 * 初始化游戏玩家缓存
	 */
	public static boolean init() {
		driverUserMap = new ConcurrentHashMap<Integer, DriverUser>();
		commonUserMap = new ConcurrentHashMap<Integer, CommonUser>();
		return true;
	}

	
	/**
	 * 获取一个用户
	 * @param userId
	 * @return
	 */
	public static User getGamePlayer(int userId,int type) {
		User user = null;
		// 从内存中查找
		if (isExist(userId,type)) {
			if(type==StaticData.userType.COMMON_USER.getType()){
				user = commonUserMap.get(userId);
			}else if(type==StaticData.userType.DRIVER_USER.getType()){
				user = driverUserMap.get(userId);
			}
			return user;
		}
		
		if(type==StaticData.userType.COMMON_USER.getType()){
			// 从数据库中加载用户信息
			UserInfo userInfo = DaoMgr.getUserInfoDao().getUserInfoById(userId);
			if(userInfo==null){
				LogUtil.error("数据库中不存在 userId : " + userId);
				return null;
			}
			// 从数据库中加载共享信息
			CommonUser commonUser = new CommonUser();
			if (!commonUser.loadData(userInfo)) {
				LogUtil.error("实例化用户 userId : " + userId + " ShareData 失败，请检查数据库初始化");
				return null;
			}
			commonUserMap.put(userId, commonUser);
			user = commonUser;
		}else if(type==StaticData.userType.DRIVER_USER.getType()){
			// 从数据库中加载用户信息
			DriverInfo driverInfo = DaoMgr.getDriverInfoDao().getDriverInfoById(userId);
			if(driverInfo==null){
				LogUtil.error("数据库中不存在 driverUser : " + userId);
				return null;
			}
			// 从数据库中加载共享信息
			DriverUser driverUser = new DriverUser();
			if (!driverUser.loadData(driverInfo)) {
				LogUtil.error("实例化司机 userId : " + userId + " ShareData 失败，请检查数据库初始化");
				return null;
			}
			driverUserMap.put(userId, driverUser);
			user = driverUser;
		}
		
		return user;
	}

	/**
	 * 获取一个用户
	 * @param userId
	 * @return
	 */
	public static User getGamePlayer(String openid,int type) {
		User user = null;
		
		if(type==StaticData.userType.COMMON_USER.getType()){
			// 从数据库中加载用户信息
			UserInfo userInfo = DaoMgr.getUserInfoDao().getUserIdByOpenid(openid);
			if(userInfo==null){
				LogUtil.error("数据库中不存在 openid : " + openid);
				return null;
			}
			// 从数据库中加载共享信息
			CommonUser commonUser = new CommonUser();
			if (!commonUser.loadData(userInfo)) {
				LogUtil.error("实例化用户 openid : " + openid + " ShareData 失败，请检查数据库初始化");
				return null;
			}
			commonUserMap.put(userInfo.getId(), commonUser);
			user = commonUser;
		}else if(type==StaticData.userType.DRIVER_USER.getType()){
			// 从数据库中加载用户信息
			DriverInfo driverInfo = DaoMgr.getDriverInfoDao().getDriverInfoByOpenid(openid);
			if(driverInfo==null){
				LogUtil.error("数据库中不存在 driverUser : " + openid);
				return null;
			}
			// 从数据库中加载共享信息
			DriverUser driverUser = new DriverUser();
			if (!driverUser.loadData(driverInfo)) {
				LogUtil.error("实例化司机 openid : " + openid + " ShareData 失败，请检查数据库初始化");
				return null;
			}
			driverUserMap.put(driverInfo.getId(), driverUser);
			user = driverUser;
		}
		
		return user;
	}

	/**
	 * 生成一個用戶
	 * @param openid
	 * @param type
	 * @return
	 */
	public static User createGamePlayer(String openid,int type) {
		User user = null;
		if(type==StaticData.userType.COMMON_USER.getType()||
			type==StaticData.userType.CHANNEL_USER.getType()){
			CommonUser commonUser = new CommonUser();
			UserInfo userInfo = commonUser.createUserInfo(openid);
			commonUser.loadData(userInfo);
			commonUserMap.put(userInfo.getId(), commonUser);
			user = commonUser;
		}else if(type==StaticData.userType.DRIVER_USER.getType()||
			type==StaticData.userType.CHECK_USER.getType()){
			DriverUser driverUser = new DriverUser();
			DriverInfo driverInfo = driverUser.createUserInfo(openid);
			driverUser.loadData(driverInfo);
			driverUserMap.put(driverInfo.getId(), driverUser);
			user = driverUser;
		}
		return user;
	}

	public static void UpdatePlayerInfo(User user,int type,String image,String nickname,int sex,String ip) {
		if(type==StaticData.userType.COMMON_USER.getType()
			||type==StaticData.userType.CHANNEL_USER.getType()){
			CommonUser commonUser = (CommonUser) user;
			commonUser.getUserInfo().setImage(image);
			commonUser.getUserInfo().setUserName(nickname);
			commonUser.getUserInfo().setSex(sex);
			commonUser.getUserInfo().setLoginDate(TimeUtil.getSysteCurTime());
			commonUser.getUserInfo().setLoginIp(ip);
		}else if(type==StaticData.userType.DRIVER_USER.getType()
			||type==StaticData.userType.CHECK_USER.getType()){
			DriverUser driverUser = (DriverUser) user;
			driverUser.getDriverInfo().setLoginDate(TimeUtil.getSysteCurTime());
			driverUser.getDriverInfo().setLoginIp(ip);
		}
	}
	/**
	 * 判断玩家是否在线
	 * @param playerId
	 * @return
	 */
	public static boolean isOnline(int playerId) {
		if (commonUserMap.containsKey(playerId)) {
			return commonUserMap.get(playerId).isOnline();
		}
		return false;
	}

	/**
	 * 发送信息
	 * @param channel
	 * @param json
	 */
	public static void sendMsg(Channel channel,JSONObject json){
		channel.writeAndFlush(new TextWebSocketFrame(json.toString()));
	}

	/**
	 * 发送给全服玩家
	 * @param packet
	 */
	public static void sendPacketAllUser(JSONObject json) {
		List<CommonUser> players = getAllUser();
		for (CommonUser player : players) {
			player.sendPacket(json);
		}
	}
	/**
	 * 发送给全服司机
	 * @param json
	 */
	public static void sendPacketAllDriver(JSONObject json) {
		List<DriverUser> players = getAllDriver();
		for (DriverUser player : players) {
			player.sendPacket(json);
		}
	}
	/**
	 * 用户是否存在
	 * @param userId
	 * @return
	 */
	public static boolean isExist(int userId,int type) {
		if(type==StaticData.userType.COMMON_USER.getType()
			||type==StaticData.userType.CHANNEL_USER.getType()){
			return commonUserMap.containsKey(userId);
		}else if(type==StaticData.userType.DRIVER_USER.getType()
			||type==StaticData.userType.CHECK_USER.getType()){
			return driverUserMap.containsKey(userId);
		}
		return false;
	}

//	/**
//	 * 玩家缓存数据同步到数据库
//	 */
//	public static void save() {
//		// 保存玩家数据
//		savePlayerData();
//	}

	/**
	 * 获取在线车主
	 */
	private static List<CommonUser> getAllUser() {
		if (commonUserMap == null) {
			return new ArrayList<CommonUser>();
		}
		return new ArrayList<CommonUser>(commonUserMap.values());
	}

	/**
	 * 获取所有司机
	 * @return
	 */
	private static List<DriverUser> getAllDriver() {
		if (driverUserMap == null) {
			return new ArrayList<DriverUser>();
		}
		return new ArrayList<DriverUser>(driverUserMap.values());
	}
	/**
	 * 保存玩家数据
	 */
	public static void saveData() {
	    System.out.println("在线车主数量："+commonUserMap.size());
		try{
			List<CommonUser> playerList = getAllUser();
			for (CommonUser user : playerList) {
				user.save();
				if (TimeUtil.getSysCurTimeMillis() / 1000 - user.getUserInfo().getLastUseTime() > 5 * 60) {
					if (user.getUserInfo().getOp() == Option.None) {
						user.getUserInfo().setOp(Option.Close);
					} else if (user.getUserInfo().getOp() == Option.Close) { // 清除离线玩家数据
						// 离线超过五分钟
						commonUserMap.remove(user.getUserInfo().getId());
						LogUtil.info(user.isOnline() + "清除玩家User缓存数据:"+ user.getUserInfo().getId());
					}
				}
			}
		}catch(Exception e){
			LogUtil.error("保存USER数据报错");
		}
		
		System.out.println("在线司机数量："+driverUserMap.size());
		try{
			List<DriverUser> driverList = getAllDriver();
			for (DriverUser user : driverList) {
				user.save();
				if (TimeUtil.getSysCurTimeMillis() / 1000 - user.getDriverInfo().getLastUseTime() > 5 * 60) {
					if (user.getDriverInfo().getOp() == Option.None) {
						user.getDriverInfo().setOp(Option.Close);
					} else if (user.getDriverInfo().getOp() == Option.Close) { // 清除离线玩家数据
						// 离线超过五分钟
						commonUserMap.remove(user.getDriverInfo().getId());
						LogUtil.info(user.isOnline() + "清除玩家Driver缓存数据:"+ user.getDriverInfo().getId());
					}
				}
			}
		}catch(Exception e){
			LogUtil.error("保存Driver数据报错");
		}
		
		//保存用户订单
		UserOrderMgr.save();
		//保存服务订单
		DriverOrderMgr.save();

	}




}
